/*
 * Путешествие коня
 * vim:foldmethod=marker:
 */
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <ctype.h>

#ifdef OLD
#undef OLD
#endif
static const char *_fmt = "would enqueue %c%c\n";

#ifdef DEBUG
# define debug_fprintf(x) fprintf x
#else
# define debug_fprintf(x) ((void)0)
#endif

struct queue {
	int	*data;
	int	head;
	int	size;
	int	size_max;
};

struct Node {
	int x;
	int8_t is_valid;
	int edge_i;
	struct Node *next;
};

struct adjlist {
	struct Node	*first;
	struct Node	*last;
	int8_t	size;
	uint8_t	visited;
	int	dist;
	int	prev;
};

static struct chess_map {
	int8_t		visited;
	int8_t		enqueued;
	short		prev;
	short		dist;
} _map[64 + 1];

static int _d[] = { -17,  -15,

             -10,                -6,

              6,                 10,

                    15,   17 };

static int _y[] = {     -1, 1,
                      -2,      2,
                      -2,      2,
                        -1, 1,     };

/*
 * ranks: rows 1..8
 * files: columns a..h
 */

/* {{{ queue and adjlist interface functions */
void
queue_init(struct queue *q, int size)
{
	q->data = (int *) calloc(size, sizeof *q->data);
	q->head = 0;
	q->size = 0;
	q->size_max = size;
}

void
enqueue(struct queue *q, const int x)
{
	if (q->size >= q->size_max)
		fprintf(stderr, "queue overflow. failed to add x=%d\n", x);
	else
		q->data[(q->head + q->size++) % q->size_max] = x;
}

int
dequeue(struct queue *q)
{
	int ret = q->data[q->head % q->size_max];
	if (!q->size)
		return ret; /* a.k.a. UB */
	--q->size;
	if (++q->head == q->size_max)
		q->head = 0;
	return ret;
}

unsigned char
queue_isempty(const struct queue *q)
{
	return (q->size > 0) ? 0 : 1;
}

void
pushback(struct adjlist *al, int x, int edge_i)
{
	struct Node *newnode;
	newnode = (struct Node *) calloc(1UL, sizeof (struct Node));
	newnode->x        = x;
	newnode->is_valid = 1;
	newnode->edge_i   = edge_i;
	newnode->next     = NULL;
	if (!al->first)
		al->first = newnode;
	else
		al->last->next = newnode;
	al->last = newnode;
	al->size++;
}

void
free_al(struct adjlist *al)
{
	struct Node *n, *p;
	p = n = al->first;
	while (n) {
		n = n->next;
		free(p);
		p = n;
	}
}
/* }}} */

inline int
s_to_int(const char *s)
{
	int rank, file, result;

	file = isupper(s[0]) ? s[0] - 'A' : s[0] - 'a';
	rank = s[1] - '1';
	result = rank * 8 + file;

	return result;
}

void
print_path(const int finish)
{
	static int path[64+1];
	int n = 0;
	int s = finish;

	while (s != -1) {
#ifdef DEBUG
		(void) fprintf(stderr, "assigning s=%d to path[%d]\n",
				s, n);
#endif
		path[n++] = s;
		s = _map[s].prev;
	}

	while (n-- > 0) {
		/*
		 * print correct square name
		 */
		putchar('a' + (path[n] % 8));
		putchar('1' + path[n] / 8);
		putchar('\n');
	}
}

int
bfs_chess(struct queue *q, const int start, const int final)
{
	short int index = start;
	static char w[3];
	register int i;

	_map[index].visited =  1;
	_map[index].prev    = -1;
	_map[index].dist    =  0;
	enqueue(q, index);

	while (!queue_isempty(q)) {
		index = dequeue(q);
#ifdef DEBUG
		w[0] = 'a' + (index % 8);
		w[1] = '1' + (index / 8);
		(void) fprintf(stderr, "index=%*s\n", 2 + _map[index].dist, w);
#endif
		_map[index].visited = 1;
		if (index == final) {
			print_path(index);
			return 0;
		}

		for (i = 0; i < sizeof _d / sizeof _d[0]; i++) {
			if ((index + _d[i]) / 8 <= 8 && (index + _d[i]) >= 0 &&
			    (index & 07) + _y[i] >= 0 && (index & 07) + _y[i] <= 8 &&
			    !_map[index + _d[i]].visited && !_map[index + _d[i]].enqueued) {
#ifdef DEBUG
				fprintf(stderr, "%s(): enqueue ", __func__);
				fputc('a' + ((index + _d[i]) % 8), stderr);
				fputc('1' + (index + _d[i]) / 8, stderr);
				fputc('\n', stderr);
#endif /* #ifdef DEBUG */
				enqueue(q, index + _d[i]);
				_map[index + _d[i]].enqueued = 1;
				_map[index + _d[i]].prev = index;
				_map[index + _d[i]].dist = _map[index].dist + 1;
			}
		}
#ifdef DEBUG1
		if ((index + 15) / 8 <= 8 && (index % 8) - 1 >= 0 && !_map[index+15].visited)
			debug_fprintf((stderr, _fmt, 'a' + ((index + 15)&7), '1' + (index + 15) / 8));
		if ((index + 17) / 8 <= 8 && (index % 8) + 1 <= 8 && !_map[index+17].visited)
			debug_fprintf((stderr, _fmt, 'a' + ((index + 17)&7), '1' + (index + 17) / 8));
		if ((index + 10) / 8 <= 8 && (index % 8) + 2 <= 8 && !_map[index+10].visited)
			debug_fprintf((stderr, _fmt, 'a' + ((index + 10)&7), '1' + (index + 10) / 8));
		if ((index - 6) >= 0 && (index - 6) / 8 >= 0 && (index % 8) + 2 <= 8 && !_map[index-6].visited)
			debug_fprintf((stderr, _fmt, 'a' + ((index - 6)&7), '1' + (index - 6) / 8));
		if ((index - 15) >= 0 && (index - 15) / 8 >= 0 && (index % 8) + 1 <= 8 && !_map[index-15].visited)
			debug_fprintf((stderr, _fmt, 'a' + ((index - 15)&7), '1' + (index - 15) / 8));
		if ((index - 17) >= 0 && (index - 17) / 8 >= 0 && (index % 8) - 1 >= 0 && !_map[index-17].visited)
			debug_fprintf((stderr, _fmt, 'a' + ((index - 17)&7), '1' + (index - 17) / 8));
		if ((index - 10) >= 0 && (index - 10) / 8 >= 0 && (index % 8) - 2 >= 0 && !_map[index-10].visited)
			debug_fprintf((stderr, _fmt, 'a' + ((index - 10)&7), '1' + (index - 10) / 8));
		if ((index + 6) / 8 <= 8 && (index % 8) - 2 >= 0 && !_map[index+6].visited)
			debug_fprintf((stderr, _fmt, 'a' + ((index + 6)&7), '1' + (index + 6) / 8));
#endif
	}

	return 0xFADE;
}

int
main(void)
{
	struct queue	q;
	int		start, finish;
	char		s_start[3], s_finish[3];

	(void) scanf("%s%s", s_start, s_finish);
	queue_init(&q, 64*9);
	start  = s_to_int(s_start);
	finish = s_to_int(s_finish);

	bfs_chess(&q, start, finish);

	free(q.data);
	return 0;
}
